package sessionBeans;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import objects.AbilityObject;
import objects.HelpmeetingObject;
import objects.MessageObject;
import objects.RequestNotificationObject;
import objects.UserObject;
import entityBeans.Ability;
import entityBeans.Helpmeeting;
import entityBeans.Message;
import entityBeans.RequestNotification;
import entityBeans.User;

/**
 *
 * @author user
 */

@Stateless
public class UserFacade extends AbstractFacade<User> implements UserFacadeLocal {
    @PersistenceContext(unitName = "sw2")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        return em;
    }

    public UserFacade() {
        super(User.class);
    }
    

	@Override
	public List<User> findAll() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<User> findRange(int[] range) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int count() {
		// TODO Auto-generated method stub
		return 0;
	}

	
	/*
	 * checked it must be true
	 * 
	 * (non-Javadoc)
	 * @see sessionBeans.UserFacadeLocal#getHelpmeetingsOfUser(entityBeans.User)
	 */
	@Override
	public Collection<HelpmeetingObject> getHelpmeetingsOfUser(User user)
			throws BeanException {
		
		if(user == null){
			throw new BeanException("There is no such User");
		}else{
		
			Query q;
			q = em.createQuery( "select p.Meeting_ID from participates p where p.User_ID =: u_id" );
			q.setParameter("u_id", user.getUserID());
			
			List<Integer> meetingIDs = (List<Integer>) q.getResultList();
			
			Collection<HelpmeetingObject> meetings = new ArrayList<HelpmeetingObject>();
			
			for (int i=0; i<meetingIDs.size(); i++){
				
				Query q1;
				q1 = em.createQuery("SELECT h FROM Helpmeeting h WHERE h.meetingID = :meetingID" );
				q1.setParameter("meetingID", meetingIDs.get(i));
				
				meetings.add((HelpmeetingObject) q1.getSingleResult());
			}
		
			return meetings;
		}
	}

	
	/*
	 * (non-Javadoc)
	 * 
	 * Checked it must be true
	 * 
	 * @see sessionBeans.UserFacadeLocal#getFriendsOfUser(entityBeans.User)
	 */
	@Override
	public Collection<UserObject> getFriendsOfUser(User user)
			throws BeanException {
		
		if(user == null){
			throw new BeanException("There is no such User");
		}else{
			Query q;
			q = em.createQuery( "select f.User_ID from friendship f where f.User_ID =: User_ID" );
			q.setParameter("User_ID", user.getUserID());
			
			List<Integer> friendIDs = (List<Integer>) q.getResultList();
			
			Collection<UserObject> friends = new ArrayList<UserObject>();
			
			for (int i=0; i<friendIDs.size(); i++){
				
				Query q1;
				q1 = em.createQuery( "select u from user u where u.User_ID =: User_ID" );
				q1.setParameter("User_ID", friendIDs.get(i));
				
				friends.add((UserObject) q1.getSingleResult());
			}
			
			return friends;
		}
	}

	
	/*
	 * Checked it must be true
	 * 
	 * (non-Javadoc)
	 * @see sessionBeans.UserFacadeLocal#getMessagesOfUser(entityBeans.User)
	 */
	@Override
	public Collection<MessageObject> getMessagesOfUser(User user)
			throws BeanException {
		
		if(user == null){
			throw new BeanException("There is no such User");
		}else{
			Query q;
			q = em.createQuery( "select sm.Message_ID from sendmessage sm where sm.User_ID =: User_ID" );
			q.setParameter("User_ID", user.getUserID());
			
			List<Integer> messageIDs = (List<Integer>) q.getResultList();
			
			Collection<MessageObject> messages = new ArrayList<MessageObject>();
			
			for (int i=0; i<messageIDs.size(); i++){
				
				Query q1;
				q1 = em.createQuery( "select m from message m where m.Message_ID =: Message_ID" );
				q1.setParameter("Message_ID", messageIDs.get(i));
				
				messages.add((MessageObject) q1.getSingleResult());
			}
			
			return messages;
		}
	}

	
	//Maybe we need some join or I need to think about it 
	
	@Override
	public Collection<RequestNotificationObject> getNotificationsOfUser(
			User user) throws BeanException {
		
		if(user == null){
			throw new BeanException("There is no such User");
		}else{
			Query q;
			q = em.createQuery( "SELECT r FROM RequestNotification r WHERE r.receiver = :receiver" );
			q.setParameter("receiver", user.getUserID());
			
			Collection<RequestNotificationObject> notifications = (Collection<RequestNotificationObject>)q.getResultList();
			
			return notifications;
		}
	}

	
	/*
	 * Checked it must be true
	 * 
	 * (non-Javadoc)
	 * @see sessionBeans.UserFacadeLocal#getAbilitiesOfUser(entityBeans.User)
	 */
	@Override
	public Collection<AbilityObject> getAbilitiesOfUser(User user)
			throws BeanException {
		
		if(user == null){
			throw new BeanException("There is no such User");
		}else{
			Query q;
			q = em.createQuery( "select a.A_ID from able a where a.User_ID =: User_ID" );
			q.setParameter("User_ID", user.getUserID());
			
			List<Integer> abilityIDs = (List<Integer>) q.getResultList();
			
			Collection<AbilityObject> messages = new ArrayList<AbilityObject>();
			
			for (int i=0; i<abilityIDs.size(); i++){
				
				Query q1;
				q1 = em.createQuery( "select a from ability a where a.A_ID =: A_ID" );
				q1.setParameter("A_ID", abilityIDs.get(i));
				
				messages.add((AbilityObject) q1.getSingleResult());
			}
			
			return messages;
		}
		
	}

	@Override
	public void addAbility(User user, Ability ability)
			throws BeanException {
		if(user == null){
			throw new BeanException("There is no such User");
		}else{
			if(ability.getName()==null){
				throw new BeanException("Ability name should not be empty!");
			}else{
				user.getAbilityCollection().add(ability);
				ability.getUserCollection().add(user);
				
				em.persist(user);
				em.persist(ability);
			}
		}
	}

	@Override
	public void addHelpmeeting(User user, Helpmeeting meeting)
			throws BeanException {
		if(user == null){
			throw new BeanException("There is no such User");
		}else{
			if(meeting.getUserCollection()==null){
				throw new BeanException("There can not be a meeting without user!");
			}else{
				user.getHelpmeetingCollection().add(meeting);
				meeting.getUserCollection().add(user);
				
				em.persist(user);
				em.persist(meeting);
			}
		}
		
	}

//	@Override
//	public void addMessage(User user, Message message)
//			throws BeanException {
//		
//		if(user == null){
//			throw new BeanException("There is no such User");
//		}else{
//			if(meeting.getUserCollection()==null){
//				throw new BeanException("There can not be a meeting without user!");
//			}else{
//				user.getHelpmeetingCollection().add(meeting);
//				meeting.getUserCollection().add(user);
//				
//				em.persist(user);
//				em.persist(meeting);
//			}
//		}
//		
//	}

	@Override
	public void addRequest(User user, RequestNotification request)
			throws BeanException {
			
		if(user==null){
			throw new BeanException("There is no such user!");			
		}else{
			
			user.getRequestNotificationCollection().add(request);
			request.setUser(user);
			
			em.persist(user);
			em.persist(request);
		}
		
	}

	@Override
	public void addMessage(User user, Message message,
			RequestNotification request) throws BeanException {
		
		if(user==null){
			throw new BeanException("There is no such user!");			
		}else{
			if(message==null){
				throw new BeanException("Empty message!");
			}else{
				if(request==null){
					throw new BeanException("Empty message request!");
				}else{
					user.getMessageCollection().add(message);
					addRequest(user, request);
					
					message.setUser(user);
					em.persist(message);
					
				}
			}
		}
		
	}
	
	
	// idea the user (receiver of notif.) get notification and adds
	// the sender of notif. to friend list also in other way
	// think about it again but i think you are close 
	@Override
	public void addFriend(User user, RequestNotification request)
			throws BeanException {
		if(request.getUser()!= null || request.getReceiver()!= user.getUserID()){
			User userSender= new User(request.getUser().getUserID());
			user.getUserCollection().add(userSender);
			
			userSender.getUserCollection().add(user);
			
			em.persist(userSender);
			em.persist(user);
		}else{
			throw new BeanException("Wrong user!!");
		}
	}
  
}